﻿using System.Collections.Generic;
using System.Xml.Schema;
using System.Xml.Linq;
using System;
using System.Xml;
using System.Diagnostics;
using cz.muni.fi.pb138.AdminService;
using System.Text;
using cz.muni.fi.pb138.QueryService;
using System.Windows.Forms;
using cz.muni.fi.pb138.Sessions;
using cz.muni.fi.pb138.XML;

namespace cz.muni.fi.pb138
{
    public class MediaManager : IMediaManager
    {
        public List<Media> Medias { get; private set; }
        public static string Login { get; set; }
        private static MediaManager instance;

		/// <summary>
		/// Media Manager works as a singletone
		/// </summary>
        public static MediaManager Single
        {
            get
            {
                if (instance == null)
                { instance = new MediaManager(); }
                return instance;
            }
        }

		/// <summary>
		/// event triggered every time the database has changed.
		/// </summary>
        public event EventHandler DatabaseChanged;

		/// <summary>
		/// a call that triggers the DatabaseChanged event
		/// </summary>
        private void OnDatabaseChanged()
        {
            if (DatabaseChanged != null)
                DatabaseChanged(this, null);
        } 

        private MediaManager()
        {
            RefreshMediaDatabase();
        }

		/// <summary>
		/// refreshes the private collection of Medias from the database.
		/// </summary>
        private void RefreshMediaDatabase()
        {
            Medias = FindAllMedias();
            OnDatabaseChanged();
        }


		/// <summary>
		/// adds new media to the database and refreshes the media list.
		/// </summary>
		/// <param name="media">New media instance to be stored</param>
		/// <returns>created <c>Media</c></returns>
        public Media CreateMedia(Media media)
        {

            XElement mediaAsXml = media;

            if (!XmlHelper.ValidateXML(mediaAsXml))
                return null;

            using (QuerySession query = new QuerySession())
            {
                media = query.GetMediaById(media.Id);
                if (media != null)
                {
                    MessageBox.Show("Medium with this original name already exists!");
                    return null;
                }
            }

            int result;
            using (AdminSession session = new AdminSession())
            {
                result = session.StoreMedium(mediaAsXml);
            }

            if (result > 0)
            {
                RefreshMediaDatabase();
                return media;
            }
            else
                return null;
        }

		/// <summary>
		/// Updates media in the DB according to the given one
		/// </summary>
		/// <param name="media">a master according to which the media in DB is updated</param>
        public void UpdateMedia(Media media)
        {
            if (!XmlHelper.ValidateXML(media))
                return;

            using (AdminSession session = new AdminSession())
            {
                session.UpdateMedium(media);
            }
            RefreshMediaDatabase();
        }

		/// <summary>
		/// Removes certain media from the DB
		/// </summary>
		/// <param name="media">a Media to be removed</param>
        public void RemoveMedia(Media media)
        {
            if (!XmlHelper.ValidateXML(media))
                return;

            using (AdminSession session = new AdminSession())
            {
                var a = session.RemoveMedium(media);
            }
            RefreshMediaDatabase();
        }

		/// <summary>
		/// Finds certain media in the DB
		/// </summary>
		/// <param name="id">the ID of a media to be found</param>
		/// <returns>the <c>Media</c> that was to be found or null</returns>
        public Media FindMediaById(long id)
        {
            Media media;
            using (QuerySession query = new QuerySession())
            {
                media = query.GetMediaById(id);
            }

            return media;
        }

		/// <summary>
		/// Retrieves all media as <c>Media</c> from the database that contain a phrase given in the name parameter
		/// </summary>
		/// <param name="name">string that is searched for in media's original name</param>
		/// <returns>list containing all the media that contain the given string</returns>
        public IList<Media> FindMediaByName(string name)
        {
            IList<Media> medias;
            using (QuerySession query = new QuerySession())
            {
                medias = query.GetMediaByName(name);
            }
            Medias = medias as List<Media>;
            return medias;
        }

		/// <summary>
		/// Retrieves all media from the database
		/// </summary>
		/// <returns>list containing all found media</returns>
        public List<Media> FindAllMedias()
        {
            List<Media> medias;
            using (QuerySession query = new QuerySession())
            {
                medias = query.GetAllMedias() as List<Media>;
            }
            Medias = medias as List<Media>;
            return medias;
        }
    }




}



